package com.smart.community.property.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.ThreadMXBean;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 性能监控配置
 * 物业公司模块性能监控配置
 * @author Wu.Liang
 * @date 2025-01-29
 * @version 1.0
 */
@Slf4j
@Configuration
@EnableScheduling
public class PerformanceMonitorConfig {
    
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    /**
     * 内存监控
     */
    @Scheduled(fixedRate = 300000) // 每5分钟执行一次
    public void monitorMemory() {
        try {
            log.info("=== 内存监控 ===");
            log.info("时间: {}", LocalDateTime.now().format(FORMATTER));
            
            Runtime runtime = Runtime.getRuntime();
            long totalMemory = runtime.totalMemory();
            long freeMemory = runtime.freeMemory();
            long maxMemory = runtime.maxMemory();
            
            MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
            MemoryUsage heapMemoryUsage = memoryBean.getHeapMemoryUsage();
            MemoryUsage nonHeapMemoryUsage = memoryBean.getNonHeapMemoryUsage();
            
            log.info("总内存: {} MB", totalMemory / 1024 / 1024);
            log.info("空闲内存: {} MB", freeMemory / 1024 / 1024);
            log.info("最大内存: {} MB", maxMemory / 1024 / 1024);
            log.info("内存使用率: {}%", ((totalMemory - freeMemory) * 100) / totalMemory);
            
            log.info("堆内存使用: {}/{} MB ({}%)", 
                    heapMemoryUsage.getUsed() / 1024 / 1024,
                    heapMemoryUsage.getMax() / 1024 / 1024,
                    (heapMemoryUsage.getUsed() * 100) / heapMemoryUsage.getMax());
            
            log.info("非堆内存使用: {}/{} MB ({}%)", 
                    nonHeapMemoryUsage.getUsed() / 1024 / 1024,
                    nonHeapMemoryUsage.getMax() / 1024 / 1024,
                    (nonHeapMemoryUsage.getUsed() * 100) / nonHeapMemoryUsage.getMax());
            
            // 内存使用率超过80%时告警
            if ((heapMemoryUsage.getUsed() * 100) / heapMemoryUsage.getMax() > 80) {
                log.warn("堆内存使用率过高，当前使用率: {}%", 
                        (heapMemoryUsage.getUsed() * 100) / heapMemoryUsage.getMax());
            }
            
            // 内存使用率超过90%时告警
            if (((totalMemory - freeMemory) * 100) / totalMemory > 90) {
                log.warn("系统内存使用率过高，当前使用率: {}%", 
                        ((totalMemory - freeMemory) * 100) / totalMemory);
            }
        } catch (Exception e) {
            log.error("内存监控失败", e);
        }
    }
    
    /**
     * 系统负载监控
     */
    @Scheduled(fixedRate = 600000) // 每10分钟执行一次
    public void monitorSystemLoad() {
        try {
            log.info("=== 系统负载监控 ===");
            log.info("时间: {}", LocalDateTime.now().format(FORMATTER));
            
            Runtime runtime = Runtime.getRuntime();
            int availableProcessors = runtime.availableProcessors();
            
            log.info("可用处理器数: {}", availableProcessors);
            
            // 这里可以添加更多的系统负载监控逻辑
            // 比如CPU使用率、磁盘使用率等
            
        } catch (Exception e) {
            log.error("系统负载监控失败", e);
        }
    }
    
    /**
     * 线程监控
     */
    @Scheduled(fixedRate = 300000) // 每5分钟执行一次
    public void monitorThreads() {
        try {
            log.info("=== 线程监控 ===");
            log.info("时间: {}", LocalDateTime.now().format(FORMATTER));
            
            ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
            int threadCount = threadBean.getThreadCount();
            int peakThreadCount = threadBean.getPeakThreadCount();
            int daemonThreadCount = threadBean.getDaemonThreadCount();
            
            log.info("当前线程数: {}", threadCount);
            log.info("峰值线程数: {}", peakThreadCount);
            log.info("守护线程数: {}", daemonThreadCount);
            
            // 线程数超过200时告警
            if (threadCount > 200) {
                log.warn("线程数过多，当前线程数: {}", threadCount);
            }
            
        } catch (Exception e) {
            log.error("线程监控失败", e);
        }
    }
} 